package androcr.client.mobile.services.fileuploader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;


import androcr.client.mobile.core.Controller;
import androcr.client.mobile.core.jsonprocessor.JSONProcessor;
import androcr.client.mobile.exceptions.MyJSONException;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.util.Base64;
import android.util.Log;

public class Uploader {
	private static final String TAG = "Uploader";
	private Context context;
	private byte[] data;
	private List<IUploadCompleteListener> listeners = new ArrayList<IUploadCompleteListener>();

	private final String url = "http://192.168.0.176:8080/andrOCR_server_servlet/upload";// TODO

	public void uploadImage(Context context, byte[] data) {
		this.context = context;
		this.data = data;
		Log.i(TAG, "exec elott");
		new UploadAsyncTask().execute(context);
		Log.i(TAG, "exec utan");

	}

	public void uploadImage(byte[] data) throws MyJSONException {
		Log.i(TAG, "data " + data);
		// Create a new HttpClient and Post Header
		HttpClient httpclient = new DefaultHttpClient();
		HttpPost httppost = new HttpPost(url);

		try {
			String base64Data = Base64.encodeToString(data, 0);
			JSONObject jsonRequest = new JSONObject();
			
			Log.i(TAG, "deviceid " + Controller.getInstance().getDeviceID(context));
			jsonRequest.put("uuid", Controller.getInstance().getDeviceID(context));
			
			jsonRequest.put("img", base64Data);
			// Add data
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
			nameValuePairs.add(new BasicNameValuePair("jsonUpload", jsonRequest
					.toString()));
			httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

			// execute HTTP Post Request
			HttpResponse response = httpclient.execute(httppost);

			// get reply
			HttpEntity entity = response.getEntity();
			InputStream is = entity.getContent();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));


			String line;
			String receivedText = "";
			while ((line = br.readLine()) != null) {
				receivedText += line;
			}
			br.close();

			JSONProcessor jsonProc = new JSONProcessor();
			JSONObject jsonResponse = jsonProc.processJSONString(receivedText);

			Log.d(TAG, "uploader xxxxxxxxxxxx " + jsonResponse);

			if (jsonResponse.has("err")) {
				String errorMsg = (String) jsonResponse.get("err");
				throw new MyJSONException(errorMsg);
			}

			String recognizedText = "";
			if (jsonResponse.has("recText")) {
				recognizedText = (String) jsonResponse.get("recText");
			}
			if ((recognizedText == null) || (recognizedText.equals(""))) {
				throw new MyJSONException(
						MyJSONException.NO_RECOGNIZED_TEXT);
			}

			Log.d(TAG, "elment vala   - " + recognizedText);
			Controller.getInstance().setActualRecognizedText(recognizedText);
		} catch (ClientProtocolException e) {
			throw new MyJSONException(MyJSONException.DEF_ERROR);
		} catch (IOException e) {
			throw new MyJSONException(MyJSONException.HTTP_ERROR);
		} catch (JSONException e) {
			e.printStackTrace();
			throw new MyJSONException(MyJSONException.IMG_ERROR);
		}
	}

	public void addUploadCompleteListener(IUploadCompleteListener ucl) {
		listeners.add(ucl);
	}

	public void notifyListeners() {
		for (IUploadCompleteListener ucl : listeners) {
			ucl.isComplete();
		}
	}

	private class UploadAsyncTask extends AsyncTask<Context, String, String> {
		private ProgressDialog dialog = new ProgressDialog(context);
		private AlertDialog alertDialog = new AlertDialog.Builder(context)
				.create();
		private String errorMessage = null;

		protected void onPreExecute() {
			dialog.setMessage("Uploading and processing data... Please wait...");
			dialog.show();
		}

		@Override
		protected String doInBackground(Context... arg0) {
			Log.i(TAG, "doinbackgr 1");
			try {
				uploadImage(data);
			} catch (MyJSONException e) {
				errorMessage = e.getMessage();
			}
			Log.i(TAG, "doinbackgr 2");
			return "Done";
		}

		@Override
		protected void onPostExecute(String unused) {
			if (this.dialog.isShowing()) {
				this.dialog.dismiss();
			}

			if (errorMessage != null) {
				alertDialog.setTitle("Alert");
				alertDialog.setMessage(errorMessage);
				// alertDialog.setIcon(R.drawable.icon);
				alertDialog.setButton("OK",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int which) {
								alertDialog.dismiss();
							}
						});
				alertDialog.show();
			}
			Log.i(TAG, "on post: " + unused);
			notifyListeners();
		}
	}

}